#-*- coding:utf-8 -*-
# 执行本模块将会做以下工作
# 1 遍历指定目录下所有的IP拓扑信息文件，并分析
# 2 将分析结果序列化到rs_analysis文件中
import string,os,fnmatch,pickle,serialize,os.path

def transfer_ip(str_ip):
    #2.3.4.4 ???
    if string.find(str_ip,"???")!=-1:
        return 0l;
    partlist = str_ip.split(".")
    return string.atoi(partlist[0])*255*255*255+string.atoi(partlist[1])*255*255+string.atoi(partlist[2])*255+string.atoi(partlist[3]);
        
def all_files(root, patterns='*', single_level=False, yield_folders=False):
    patterns = patterns.split(';')
    for path, subdirs, files in os.walk(root):
        if yield_folders:
            files.extend(subdirs)
        files.sort()
    for name in files:
        for pattern in patterns:
            if fnmatch.fnmatch(name,pattern):
                yield os.path.join(path,name)
                break
        if single_level:
            break

def getlink(filename):
    ip = transfer_ip(filename.split("\\")[-1])	#得到ip名称
    final_ip = 0

    file_object = open(filename)
    i=0
    linklist=[]    
    for line in file_object:
        if i!=0 and string.find(line,"%") != -1:
	    now_ip = transfer_ip(line[8:25].rstrip())
            linklist.append(now_ip)
	    final_ip = now_ip
        i=i+1
    file_object.close()
    if(final_ip == ip):
    	return linklist
    return None

'''
	输入:link和other_link为ip链路
	处理：link与other_link跳数不超过5；对两条链路逐跳比较，IP有差异的跳数不超过5，则此两链路在同一ISP中
	输出：link和other_link是否在同一个isp中，在同一个ISP中返回True，不在同一个ISP中返回False
'''
def same_isp(link,other_link): 
    link_len = len(link)
    other_link_len  =  len(other_link)
    distance = abs(link_len-other_link_len);
    if distance > 5:
        return False

    diff = same_isp_index(link, other_link)
    #print diff
    if(diff > 5):
        return False
    else:
        return True

def same_isp_index(link,other_link):
    diff = 0
    length = min(len(link), len(other_link))
    diff = max (len(link), len(other_link)) - length
    i = 0
    while i < length :
        if(link[i]!=0 and other_link[i]!=0 and abs(link[i]-other_link[i]) > 255*255):
            diff=diff+1
        i = i + 1 
    return diff


def getlinksfromdir(dirname):  
    all_links_list = []
    unreach = 0
    print dirname
    for path in all_files(dirname):       

        link_list = getlink(path)
        ip = path.split("\\")[-1]    #得到ip名称
        if link_list is not None:        
            all_links_list.append((ip,link_list))
        else:
            unreach = unreach + 1
            #print ip, " not reachable", str(unreach), " deleted"
            os.remove(path)
    return all_links_list

def main2(dirname = "data/resultxxxx/"):
    print "start analysis"
    #电信地标集合
    dianxin_links = getlinksfromdir(dirname + "dns_dianxin.txt")

    #联通地标IP集合
    liantong_links = getlinksfromdir(dirname + "dns_liantong.txt")

    #未分类的IP
    unkown_links = getlinksfromdir(dirname +"ip.txt");

    #classifiy unkown to liantong, dianxin, both, neither
    catagory_list = []



    for ip, link in unkown_links:
        dianxin_diff = 255
        dianxin_ip = ""

        liantong_diff = 255
        liantong_ip = ""
        for other_ip, other_link in dianxin_links:
            now_diff  = same_isp_index(link, other_link)
            if dianxin_diff > now_diff:
                dianxin_diff = now_diff        
                dianxin_ip = other_ip
        for other_ip, other_link in liantong_links:
            now_diff = same_isp_index(link, other_link)
            if liantong_diff > now_diff:
                liantong_diff = now_diff
                liantong_ip = other_ip          
        if dianxin_diff < liantong_diff:
            catagory_list.append([ip, 1, None])
        elif dianxin_diff > liantong_diff:
            catagory_list.append([ip, 2, None])
        else:
            catagory_list.append([ip, 3, None])
 
    #save to disk        
 
    serialize.save("rs_analysis",catagory_list) 
    print "analysis done"

if __name__=="__main__":
    main2()